require 'MVVM.Sources.View.Adaptor'
--直接绑定Dict
DictAdaptor = class('DictAdaptor', Adaptor)

function DictAdaptor:ctor(propertyName, prefab, binder, addCallback, removeCallback, compareFuncs)--这里不管理prefab释放，谁使用这个谁管理prefab的释放
    self.prefab = prefab
    compareFuncs = compareFuncs or {}
    local modifiedCompareFunc = {}
    for _, func in ipairs(compareFuncs) do
        table.insert(modifiedCompareFunc, function(A, B) return func(A:Get_BindingContext(), B:Get_BindingContext()) end)
    end
    self.compareFuncs = modifiedCompareFunc
    self.addCallback = addCallback
    self.removeCallback = removeCallback
    self.id2ViewDict = {}
    self:BindProperty(propertyName, binder)
end

function DictAdaptor:GetPrefab(viewModel)
    if type(self.prefab) == 'function' then
        return self.prefab(viewModel)
    else
        return self.prefab
    end
end

function DictAdaptor:OnViewModelValueChanged(oldValue, newValue)
    newValue = newValue or {}
    local addList = {}
    local removeList = {}
    --删除没有的View
    for id, view in pairs(self.id2ViewDict) do
        if newValue[id] == nil or self:GetPrefab(view:Get_BindingContext()) ~= self:GetPrefab(newValue[id])then
            table.insert(removeList, view)
            view:Set_BindingContext(nil)
            self.id2ViewDict[id] = nil
        end
    end

    for id, view in pairs(self.id2ViewDict) do
        if view:Get_BindingContext() ~= newValue[id] then
            view:Set_BindingContext(newValue[id])
        end
    end

    --增加新增的view
    for id, viewModel in pairs(newValue) do
        if self.id2ViewDict[id] == nil then
            local viewGO = GameObject.Instantiate(self:GetPrefab(viewModel))
            local view = GetLuaObject(viewGO)
            view:Set_BindingContext(viewModel)
            table.insert(addList, view)
            self.id2ViewDict[id] = view
        end
    end
    --排序
    if #self.compareFuncs > 0 then
        utils.stableSort(addList, self.compareFuncs)
        utils.stableSort(removeList, self.compareFuncs)
    end

    if self.addCallback then self.addCallback(addList) end
    if self.removeCallback then self.removeCallback(removeList) end
end